package br.ufpe.abaco.ParserGen.parser;

import br.ufpe.abaco.ParserGen.lexer.RegExp;
import br.ufpe.abaco.ParserGen.lexer.Token;

/**
 * Representa um s�mbolo terminal de uma gram�tica BNF.
 *
 * @author     Monique Monteiro e Pablo Sampaio
 * @created    30 de Outubro de 2002
 */
public class TerminalSymbol extends GrammarSymbol {

	/**
	 *  Representa o fim da string de simbolos de entrada para o parser
	 */
	public static TerminalSymbol EOF = new TerminalSymbol("$", null, 0);
	
	/**
	 *  Representa um caracter de espaco em branco
	 */
	public static TerminalSymbol BLANK = new TerminalSymbol("BLANK", null, 0);
	
	/**
	 *  Representa comentario
	 */
	public static TerminalSymbol COMMENT = new TerminalSymbol("COMMENT", null, 0);

	/**
	 *  Acao padrao sobre uma string associada ao simbolo nao-terminal (retorna a propria string)
	 */
	private static TokenAction DEFAULT_ACTION = new TokenAction() {
		public Object act(Token tk) {
			return tk.getValue();
		}
	};

	private TokenAction action;
	private RegExp regularExpression;


    // Define a prioridade do Token no analisador Lexico.
    private int priority;
    public void priority(int p) { priority=p; }
    public int  priority() { return priority; }


	TerminalSymbol(String name, int index) {
		super(name, index);
		this.action = DEFAULT_ACTION;
	}

	TerminalSymbol(String name, RegExp pattern, int index) {
		super(name, index);
		this.regularExpression = pattern;
		this.action = DEFAULT_ACTION;
	}

	public String toString() {
		return this.name;
	}

	public int hashCode() {
		return this.name.hashCode();
	}

	public void setAction(TokenAction theAction) {
		this.action = theAction;
	}

	public TokenAction getAction() {
		return this.action;
	}

	public RegExp getRegularExpression() {
		return this.regularExpression;
	}
	
	public void setRegularExpression(RegExp regularExpression){
		this.regularExpression = regularExpression;
	}

	public boolean equals(Object symbol) {
		boolean result = false;

		if (symbol instanceof TerminalSymbol
			&& ((TerminalSymbol) symbol).name.equals(this.name)) {
			result = true;
		}

		return result;
	}

}
